﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation.CApAIVCAutomaticInterferenceVolumeCreationLogic
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.InterferenceVolume;
using DnProcessSimulateCommands.SweptVolume;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation;

internal class CApAIVCAutomaticInterferenceVolumeCreationLogic
{
  private CApAIVCSweptVolumesCreator m_svCreator;
  private CApAIVCInterferenceVolumesCreator m_ivCreator;
  private CApAIVCInterferenceZonesCreator m_izCreator;
  private Dictionary<ITxRobot, TxObjectList> m_sweptVolumes;
  private TxObjectList m_interferenceVolumes;
  private TxObjectList m_redundantSweptVolumes;
  private TxSweptVolume_MayProceedCalculation m_mayProceedSVCallback;
  private TxInterferenceVolume_MayProceedCalculation m_mayProceedIVCallback;
  private bool m_shouldStop;
  private CApAIVCLogManager m_logManager;
  private CApAIVCLogMessageEventHandler m_logMessage;

  internal event NextHighLevelStepStartedEventHandler NextHighLevelStep;

  internal event NextMidLevelStepStartedEventHandler NextMidLevelStep;

  internal event LowLevelStepDurationEventHandler LowLevelStepDuration;

  internal event LowLevelStepProgressEventHandler LowLevelStepProgress;

  internal event CApAIVCLogErrorEventHandler LogError;

  internal event CApSimulationHandler_SimulationInitializedEventHandler SimulationInitialized;

  public TxSweptVolume_MayProceedCalculation SweptVolumeCallback
  {
    set => this.m_mayProceedSVCallback = value;
  }

  public TxInterferenceVolume_MayProceedCalculation InterferenceVolumeCallback
  {
    set => this.m_mayProceedIVCallback = value;
  }

  public CApAIVCAutomaticInterferenceVolumeCreationLogic()
  {
    this.m_shouldStop = false;
    this.m_logManager = new CApAIVCLogManager();
    this.m_logMessage = new CApAIVCLogMessageEventHandler(this.m_logManager.WriteStatusMessageToLog);
  }

  public void Generate(
    TxObjectList inputVolumeHolders,
    double accuracy,
    bool deleteRedundantSV,
    bool includeCables)
  {
    this.m_shouldStop = false;
    this.m_logManager.LogError += this.LogError;
    this.m_logManager.Init();
    this.ExistingVolumesDeletion(inputVolumeHolders);
    this.SweptVolumesCreation(inputVolumeHolders, accuracy, includeCables);
    if (!this.m_shouldStop)
    {
      this.InterferenceVolumesCreation();
      if (!this.m_shouldStop)
      {
        this.InterferenceZonesCreation(includeCables);
        if (!this.m_shouldStop && deleteRedundantSV)
          this.RedundantSweptVolumeDeletion();
      }
    }
    this.m_logManager.WriteNonEndedSimulationToLog();
    this.m_logManager.WriteTimeToLog();
    this.m_logManager.LogError -= this.LogError;
  }

  public void Abort(bool stopInvoked)
  {
    this.m_shouldStop = true;
    if (this.m_svCreator != null)
    {
      this.m_svCreator.AbortCreation();
      this.m_svCreator = (CApAIVCSweptVolumesCreator) null;
    }
    if (this.m_ivCreator != null)
    {
      this.m_ivCreator.AbortCreation();
      this.m_ivCreator = (CApAIVCInterferenceVolumesCreator) null;
    }
    if (this.m_izCreator != null)
    {
      this.m_izCreator.AbortCreation();
      this.m_izCreator = (CApAIVCInterferenceZonesCreator) null;
    }
    if (!stopInvoked)
      return;
    this.m_logManager.WriteStopMessageToLog();
  }

  private void ExistingVolumesDeletion(TxObjectList inputVolumeHolders)
  {
    foreach (ITxSweptVolumeHoldingObject inputVolumeHolder in (Collection<ITxObject>) inputVolumeHolders)
    {
      TxSweptVolume withClearanceType = CApSVSweptVolume.getSVWithClearanceType(inputVolumeHolder, 0.0);
      if (TxSweptVolume.op_Inequality(withClearanceType, (ITxObject) null))
        withClearanceType.Delete();
      foreach (TxInterferenceVolume interferenceVolume in CApIVUtilities.GetInterferenceVolumes(inputVolumeHolder as ITxInterferenceVolumeHoldingObject))
      {
        if (this.ShouldDeleteInterferenceVolume(interferenceVolume, inputVolumeHolders))
        {
          this.RoboticCommandsDeletion(interferenceVolume);
          interferenceVolume.Delete();
        }
      }
    }
  }

  private bool ShouldDeleteInterferenceVolume(
    TxInterferenceVolume interferenceVolume,
    TxObjectList inputVolumeHolders)
  {
    bool flag = true;
    List<ITxInterferenceVolumeHoldingObject> volumeHoldingObjects = CApIVUtilities.GetInterferenceVolumeHoldingObjects(interferenceVolume);
    for (int index = 0; index < volumeHoldingObjects.Count & flag; ++index)
      flag = ((Collection<ITxObject>) inputVolumeHolders).Contains((ITxObject) (volumeHoldingObjects[index] as ITxSweptVolumeHoldingObject));
    return flag;
  }

  private void RoboticCommandsDeletion(TxInterferenceVolume interferenceVolume)
  {
    foreach (ITxInterferenceVolumeHoldingObject volumeHoldingObject in CApIVUtilities.GetInterferenceVolumeHoldingObjects(interferenceVolume))
    {
      foreach (TxInterferenceVolumeLocationDataEx interferenceLocation in TxInterferenceVolumeEx.GetHoldingObjectInterferenceLocations(interferenceVolume, volumeHoldingObject))
      {
        TxRoboticCommand roboticCommand = interferenceLocation.RoboticCommand;
        if (TxRoboticCommand.op_Inequality(roboticCommand, (ITxObject) null))
          roboticCommand.Delete();
      }
    }
  }

  private void SweptVolumesCreation(TxObjectList svHolders, double accuracy, bool includeCables)
  {
    this.FireHighLevelProgress();
    if (this.m_shouldStop)
      return;
    this.m_logManager.BeginTime("AIVC_GENERATING_SV_OBJS");
    this.m_svCreator = new CApAIVCSweptVolumesCreator();
    this.m_svCreator.SimulationInitialized += new CApSimulationHandler_SimulationInitializedEventHandler(this.m_anyCreator_SimulationInitialized);
    this.m_svCreator.NextMidLevelStep += new NextMidLevelStepStartedEventHandler(this.OnNextMidLevelProgress);
    this.m_svCreator.Callback = this.m_mayProceedSVCallback;
    this.m_svCreator.LogMessage = this.m_logMessage;
    this.m_svCreator.SweptVolumeCreation(svHolders, accuracy, includeCables);
    if (this.m_svCreator == null || this.m_shouldStop)
      return;
    this.m_sweptVolumes = this.m_svCreator.SweptVolumes;
    this.m_svCreator.NextMidLevelStep -= new NextMidLevelStepStartedEventHandler(this.OnNextMidLevelProgress);
    this.m_svCreator = (CApAIVCSweptVolumesCreator) null;
    this.m_logManager.EndTime("AIVC_GENERATING_SV_OBJS");
  }

  private void InterferenceVolumesCreation()
  {
    this.FireHighLevelProgress();
    if (this.m_shouldStop)
      return;
    this.m_logManager.BeginTime("AIVC_DETECTING_COLLISIONS");
    this.m_ivCreator = new CApAIVCInterferenceVolumesCreator();
    this.m_ivCreator.NextMidLevelStep += new NextMidLevelStepStartedEventHandler(this.OnNextMidLevelProgress);
    this.m_ivCreator.Callback = this.m_mayProceedIVCallback;
    this.m_ivCreator.LogMessage = this.m_logMessage;
    this.m_ivCreator.SweptVolumeCollisionDetection(this.m_sweptVolumes);
    this.m_logManager.EndTime("AIVC_DETECTING_COLLISIONS");
    this.FireHighLevelProgress();
    if (this.m_ivCreator != null && !this.m_shouldStop)
    {
      this.m_logManager.BeginTime("AIVC_GENERATING_IV_OBJS");
      this.m_ivCreator.InterferenceVolumeCreation();
    }
    if (this.m_ivCreator == null || this.m_shouldStop)
      return;
    this.m_interferenceVolumes = this.m_ivCreator.InterferenceVolumes;
    this.m_redundantSweptVolumes = this.m_ivCreator.RedundantSweptVolumes;
    this.m_ivCreator.NextMidLevelStep -= new NextMidLevelStepStartedEventHandler(this.OnNextMidLevelProgress);
    this.m_ivCreator = (CApAIVCInterferenceVolumesCreator) null;
    this.m_logManager.EndTime("AIVC_GENERATING_IV_OBJS");
  }

  private void InterferenceZonesCreation(bool includeCables)
  {
    this.FireHighLevelProgress();
    if (this.m_shouldStop)
      return;
    this.m_logManager.BeginTime("AIVC_DETECTING_LOCATIONS");
    this.m_izCreator = new CApAIVCInterferenceZonesCreator();
    this.m_izCreator.SimulationInitialized += new CApSimulationHandler_SimulationInitializedEventHandler(this.m_anyCreator_SimulationInitialized);
    this.m_izCreator.NextMidLevelStep += new NextMidLevelStepStartedEventHandler(this.OnNextMidLevelProgress);
    this.m_izCreator.LowLevelStepDuration += new LowLevelStepDurationEventHandler(this.OnLowLevelDuration);
    this.m_izCreator.LowLevelStepProgress += new LowLevelStepProgressEventHandler(this.OnLowLevelProgress);
    this.m_izCreator.LogMessage = this.m_logMessage;
    this.m_izCreator.InterferenceZoneCreation(this.m_interferenceVolumes, includeCables);
    if (this.m_izCreator == null || this.m_shouldStop)
      return;
    this.m_izCreator.NextMidLevelStep -= new NextMidLevelStepStartedEventHandler(this.OnNextMidLevelProgress);
    this.m_izCreator.LowLevelStepDuration -= new LowLevelStepDurationEventHandler(this.OnLowLevelDuration);
    this.m_izCreator.LowLevelStepProgress -= new LowLevelStepProgressEventHandler(this.OnLowLevelProgress);
    this.m_izCreator = (CApAIVCInterferenceZonesCreator) null;
    this.m_logManager.EndTime("AIVC_DETECTING_LOCATIONS");
  }

  private void RedundantSweptVolumeDeletion()
  {
    this.FireHighLevelProgress();
    if (this.m_logManager.NumErrors == 0)
    {
      this.m_logManager.BeginTime("AIVC_DELETING_SV_OBJS");
      if (((Collection<ITxObject>) this.m_redundantSweptVolumes).Count == 0)
      {
        this.m_logManager.WriteStatusMessageToLog((object) this, new CApAIVCLogMessageEventArgs(new CApAIVCLogMessage(eApAIVCLogCode.SWEPT_VOLUME_DELETION_NO_VOLUMES)));
      }
      else
      {
        for (int index = 0; index < ((Collection<ITxObject>) this.m_redundantSweptVolumes).Count && !this.m_shouldStop; ++index)
        {
          TxSweptVolume redundantSweptVolume = ((Collection<ITxObject>) this.m_redundantSweptVolumes)[index] as TxSweptVolume;
          this.FireMidLevelProgress(((Collection<ITxObject>) this.m_redundantSweptVolumes).Count);
          this.m_logManager.WriteStatusMessageToLog((object) this, new CApAIVCLogMessageEventArgs(new CApAIVCLogMessage(eApAIVCLogCode.SWEPT_VOLUME_DELETION, redundantSweptVolume.Name)));
          redundantSweptVolume.Delete();
        }
      }
      this.m_logManager.EndTime("AIVC_DELETING_SV_OBJS");
    }
    else
      this.m_logManager.WriteStatusMessageToLog((object) this, new CApAIVCLogMessageEventArgs(new CApAIVCLogMessage(eApAIVCLogCode.SWEPT_VOLUME_DELETION_SKIP)));
  }

  private void FireHighLevelProgress()
  {
    if (this.NextHighLevelStep == null)
      return;
    this.NextHighLevelStep((object) this, new EventArgs());
  }

  private void FireMidLevelProgress(int nVolumes)
  {
    if (this.NextMidLevelStep == null)
      return;
    this.NextMidLevelStep((object) this, new NextMidLevelStepStartedEventArgs(nVolumes));
  }

  private void OnNextMidLevelProgress(object sender, NextMidLevelStepStartedEventArgs e)
  {
    if (this.NextMidLevelStep == null)
      return;
    this.NextMidLevelStep(sender, e);
  }

  private void OnLowLevelDuration(object sender, LowLevelStepDurationEventArgs e)
  {
    if (this.LowLevelStepDuration == null)
      return;
    this.LowLevelStepDuration(sender, e);
  }

  private void OnLowLevelProgress(object sender, EventArgs e)
  {
    if (this.LowLevelStepProgress == null)
      return;
    this.LowLevelStepProgress(sender, e);
  }

  private bool MayProceed(int progress) => !this.m_shouldStop;

  private void m_anyCreator_SimulationInitialized(object sender, EventArgs e)
  {
    if (this.SimulationInitialized == null)
      return;
    this.SimulationInitialized(sender, e);
  }
}
